home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / VARIABLE.C < prev    next >
C/C++ Source or Header  |  1989-12-31  |  16KB  |  715 lines

  1. /*
  2.  *    Variabel setting and display
  3.  */
  4.  
  5. #include "config.h"
  6.  
  7. import in_init;
  8.  
  9. import char            /* string variables */
  10.     *decode_header_file,
  11.     *default_distribution,
  12.     *default_save_file,
  13.     *extra_mail_headers,
  14.     *extra_news_headers,
  15.     *header_lines,
  16.     *folder_directory,
  17.     included_mark[],
  18.     *mail_box,
  19.     *mail_record,
  20.     *mail_script,
  21.     *news_record,
  22.     *news_script,
  23.     *pager,
  24.     *patch_command,
  25.     printer[],
  26.     *save_counter_format,
  27.     *unshar_command,
  28.     *unshar_header_file;
  29.  
  30. import int            /* boolean variables */
  31.     also_cross_postings,
  32.     also_subgroups,
  33.     auto_preview_mode,
  34.     compress_mode,
  35.     conf_append,
  36.     conf_auto_quit,
  37.     conf_create,
  38.     conf_dont_sleep,
  39.     conf_group_entry,
  40.     delay_redraw,
  41.     do_kill_handling,
  42.     dont_sort_articles,
  43.     dont_sort_folders,
  44.     dont_split_digests,
  45.     flow_control,
  46.     fmt_rptsubj,
  47.     include_art_id,
  48.     keep_rc_backup,
  49.     long_menu,
  50.     macro_debug,
  51.     mark_overlap,
  52.     monitor_mode,
  53.     nn_re_style,
  54.     novice,
  55.     quick_save,
  56.     save_report,
  57.     seq_cross_filtering,
  58.     shell_restrictions,
  59.     show_article_date,
  60.     show_current_time,
  61.     silent,
  62.     slow_mode,
  63.     use_mail_folders,
  64.     use_mmdf_folders,
  65.     use_newsrc,
  66.     use_visible_bell;
  67.  
  68. import int            /* integer variables */
  69.     also_read_articles,
  70.     article_limit,
  71.     collapse_subject,
  72.     Columns,
  73.     Debug,
  74.     first_page_lines,
  75.     fmt_linenum,
  76.     Lines,
  77.     min_pv_window,
  78.     overlap,
  79.     preview_window,
  80.     re_layout,
  81.     retry_on_error,
  82.     slow_speed,
  83.     wrap_headers;
  84.  
  85. import char            /* key strokes */
  86.     comp1_key,
  87.     comp2_key,
  88.     help_key,
  89.     erase_key,
  90.     delword_key,
  91.     kill_key;
  92.  
  93. #define    V_STRING    0
  94. #define V_BOOLEAN    1
  95. #define    V_INTEGER    2
  96. #define V_KEY        3
  97. #define    V_SPECIAL    4
  98.  
  99. #define V_SAFE        0x80
  100. #define V_INIT        0x40
  101.  
  102. struct variable_defs {
  103.     char *var_name;
  104.     char var_type;
  105.     char var_op;
  106.     char **var_addr;
  107. } variables[] = {
  108.     "also-subgroups",    V_BOOLEAN | V_INIT, 0,    (char **)&also_subgroups,
  109.     "auto-preview-mode",V_BOOLEAN,    0,    (char **)&auto_preview_mode,
  110.     "backup",        V_BOOLEAN | V_INIT, 0,    (char **)&keep_rc_backup,
  111.     "collapse-subject",    V_INTEGER,    3,    (char **)&collapse_subject,
  112.     "columns",        V_INTEGER,    1,    (char **)&Columns,
  113.     "comp1_key",    V_KEY,        0,    (char **)&comp1_key,
  114.     "comp2_key",    V_KEY,        0,    (char **)&comp2_key,
  115.     "compress",        V_BOOLEAN,    0,    (char **)&compress_mode,
  116.     "confirm-append",    V_BOOLEAN,    0,    (char **)&conf_append,
  117.     "confirm-auto-quit",V_BOOLEAN,    0,    (char **)&conf_auto_quit,
  118.     "confirm-create",    V_BOOLEAN,    0,    (char **)&conf_create,
  119.     "confirm-entry",    V_BOOLEAN,    0,    (char **)&conf_group_entry,
  120.     "confirm-messages",    V_BOOLEAN,    0,    (char **)&conf_dont_sleep,
  121.     "cross-filter-seq",    V_BOOLEAN,    0,    (char **)&seq_cross_filtering,
  122.     "cross-post",    V_BOOLEAN,    0,    (char **)&also_cross_postings,
  123.     "date",        V_BOOLEAN,    0,    (char **)&show_article_date,
  124.     "debug",        V_INTEGER,    0,    (char **)&Debug,
  125.     "decode-header-file",V_STRING,    0,    (char **)&decode_header_file,
  126.     "default-distribution",V_STRING,    0,    (char **)&default_distribution,
  127.     "default-save-file",V_STRING,    3,    (char **)&default_save_file,
  128.     "delay-redraw",    V_BOOLEAN,    0,    (char **)&delay_redraw,
  129.     "erase-key",    V_KEY,        0,    (char **)&erase_key,
  130.     "expert",        V_BOOLEAN,    4,    (char **)&novice,
  131.     "flow-control",    V_BOOLEAN,    0,    (char **)&flow_control,
  132.     "folder",        V_STRING,    2,    (char **)&folder_directory,
  133.     "fsort",        V_BOOLEAN,    2,    (char **)&dont_sort_folders,
  134.     "header-lines",    V_STRING,    0,    (char **)&header_lines,
  135.     "help-key",        V_KEY,        0,    (char **)&help_key,
  136.     "include-art-id",    V_BOOLEAN,    0,    (char **)&include_art_id,
  137.     "included-mark",    V_STRING,    1,    (char **)included_mark,
  138.     "kill",        V_BOOLEAN,    0,    (char **)&do_kill_handling,
  139.     "kill-key",        V_KEY,        0,    (char **)&kill_key,
  140.     "layout",        V_INTEGER,    1,    (char **)&fmt_linenum,
  141.     "limit",        V_INTEGER,    2,    (char **)&article_limit,
  142.     "lines",        V_INTEGER,    1,    (char **)&Lines,
  143.     "long-menu",    V_BOOLEAN,    1,    (char **)&long_menu,
  144.     "macro-debug",    V_BOOLEAN,    0,    (char **)¯o_debug,
  145.     "mail",        V_STRING,    2,    (char **)&mail_box,
  146.     "mail-format",    V_BOOLEAN,    0,    (char **)&use_mail_folders,
  147.     "mail-header",    V_STRING,    0,    (char **)&extra_mail_headers,
  148.     "mail-record",    V_STRING,    2,    (char **)&mail_record,
  149.     "mail-script",    V_STRING | V_SAFE, 2,    (char **)&mail_script,
  150.     "mark-overlap",    V_BOOLEAN,    0,    (char **)&mark_overlap,
  151.     "min-window",    V_INTEGER,    1,    (char **)&min_pv_window,
  152.     "mmdf-format",    V_BOOLEAN,    0,    (char **)&use_mmdf_folders,
  153.     "monitor",        V_BOOLEAN,    0,    (char **)&monitor_mode,
  154.     "news-header",    V_STRING,    0,    (char **)&extra_news_headers,
  155.     "news-record",    V_STRING,    2,    (char **)&news_record,
  156.     "news-script",    V_STRING | V_SAFE, 2,    (char **)&news_script,
  157.     "newsrc",        V_BOOLEAN,    0,    (char **)&use_newsrc,
  158.     "nn-re-style",    V_BOOLEAN,    0,    (char **)&nn_re_style,
  159.     "old",        V_SPECIAL,    2,    (char **)NULL,
  160.     "overlap",        V_INTEGER,    0,    (char **)&overlap,
  161.     "pager",        V_STRING | V_SAFE, 3,    (char **)&pager,
  162.     "patch-command",    V_STRING | V_SAFE, 3,    (char **)&patch_command,
  163.     "printer",        V_STRING | V_SAFE, 1,    (char **)printer,
  164.     "quick-save",    V_BOOLEAN,    0,    (char **)&quick_save,
  165.     "re-layout",    V_INTEGER,    0,    (char **)&re_layout,
  166.     "record",        V_SPECIAL,    1,    (char **)NULL,
  167.     "repeat",        V_BOOLEAN,    0,    (char **)&fmt_rptsubj,
  168.     "retry-on-error",    V_INTEGER,    0,    (char **)&retry_on_error,
  169.     "save-counter",    V_STRING,    3,    (char **)&save_counter_format,
  170.     "save-report",    V_BOOLEAN,    0,    (char **)&save_report,
  171.     "shell-restrictions", V_BOOLEAN|V_INIT, 0,    (char **)&shell_restrictions,
  172.     "silent",        V_BOOLEAN,    0,    (char **)&silent,
  173.     "slow-mode",    V_BOOLEAN,    0,    (char **)&slow_mode,
  174.     "slow-speed",    V_INTEGER,    0,    (char **)&slow_speed,
  175.     "sort",        V_BOOLEAN,    2,    (char **)&dont_sort_articles,
  176.     "split",        V_BOOLEAN,    4,    (char **)&dont_split_digests,
  177.     "stop",        V_INTEGER,    0,    (char **)&first_page_lines,
  178.     "time",        V_BOOLEAN,    0,    (char **)&show_current_time,
  179.     "unshar-command",    V_STRING | V_SAFE, 3,    (char **)&unshar_command,
  180.     "unshar-header-file",V_STRING,    0,    (char **)&unshar_header_file,
  181.     "visible-bell",     V_BOOLEAN,    0,    (char **)&use_visible_bell,
  182.     "window",        V_INTEGER,    1,    (char **)&preview_window,
  183.     "word-key",        V_KEY,        0,    (char **)&delword_key,
  184.     "wrap-header-margin",V_INTEGER,    2,    (char **)&wrap_headers
  185. };
  186.  
  187. #define TABLE_SIZE    (sizeof(variables)/sizeof(struct variable_defs))
  188.  
  189. #define INT_VAR        (*((int *)(var->var_addr)))
  190. #define BOOL_VAR    (*((int *)(var->var_addr)))
  191. #define STR_VAR        (*(var->var_addr))
  192. #define CBUF_VAR    ((char *)(var->var_addr))
  193. #define KEY_VAR        (*((unsigned char *)(var->var_addr)))
  194. #define VAR_TYPE    (var->var_type & 0xf)
  195.  
  196. static struct variable_defs *lookup_variable(variable)
  197. char *variable;
  198. {
  199.     register struct variable_defs *var;
  200.     register i, j, k, t;
  201.     
  202.     i = 0; j = TABLE_SIZE - 1; 
  203.     
  204.     while (i <= j) {
  205.     k = (i + j) / 2;
  206.     var = &variables[k];
  207.     
  208.     if ( (t=strcmp(variable, var->var_name)) > 0) 
  209.         i = k+1;
  210.     else
  211.     if (t < 0)
  212.         j = k-1;
  213.     else
  214.         return var;
  215.     }
  216.  
  217.     init_message("unknown variable: %s", variable);
  218.     return NULL;
  219. }    
  220.  
  221.  
  222. set_variable(variable, on, val_string)
  223. char *variable;
  224. int on;
  225. char *val_string;
  226. {
  227.     int value;
  228.     register struct variable_defs *var;
  229.  
  230.     if (strncmp(variable, "no", 2) == 0) {
  231.     on = !on;
  232.     variable += 2;
  233.     if (variable[0] == '-') variable++;
  234.     }
  235.     
  236.     if ((var = lookup_variable(variable)) == NULL) 
  237.     return 0;
  238.     
  239.     if (!in_init && (var->var_type & (V_INIT | V_SAFE))) {
  240.     if (var->var_type & V_INIT) {
  241.         msg("'%s' can only be set in the init file", variable);
  242.         return 0;
  243.     }
  244.     if (shell_restrictions) {
  245.         msg("Restricted operation - cannot change");
  246.         return 0;
  247.     }
  248.     }
  249.  
  250.     if (!on || val_string == NULL)
  251.     value = 0;
  252.     else    
  253.     value = atoi(val_string);
  254.  
  255.     switch (VAR_TYPE) {
  256.     
  257.      case V_STRING:
  258.  
  259.     switch (var->var_op) {
  260.      case 0:
  261.         STR_VAR = (on && val_string) ? copy_str(val_string) : (char *)NULL;
  262.         break;
  263.  
  264.      case 1:
  265.         strcpy(CBUF_VAR, (on && val_string) ? val_string : "");
  266.         break;
  267.  
  268.      case 2:
  269.         if (on) {
  270.         char exp_buf[FILENAME];
  271.         
  272.         adjust(val_string);
  273.         if (val_string) {
  274.             if (expand_file_name(exp_buf, val_string))
  275.             STR_VAR = home_relative(exp_buf);
  276.         }
  277.         } else
  278.         STR_VAR = (char *)NULL;
  279.         break;
  280.  
  281.      case 3:
  282.         if (!on || val_string == NULL) {
  283.         msg("Cannot unset string `%s'", variable);
  284.         break;
  285.         }
  286.         STR_VAR = copy_str(val_string);
  287.         break;
  288.     }
  289.     break;
  290.     
  291.      case V_BOOLEAN:
  292.     
  293.     if (val_string) on = strncmp(val_string, "off", 3);
  294.  
  295.     switch (var->var_op) {
  296.      case 0:
  297.         BOOL_VAR = on;
  298.         break;
  299.         
  300.      case 1:
  301.         BOOL_VAR = on;
  302.         return 1;
  303.         
  304.      case 2:
  305.         if (BOOL_VAR == on) {
  306.         BOOL_VAR = !on;
  307.         if (!in_init) {
  308.             if (BOOL_VAR)
  309.             unsort_articles(1);
  310.             else
  311.             sort_articles();
  312.             return 1;
  313.         }
  314.         }    
  315.         break;
  316.         
  317.      case 4:
  318.         BOOL_VAR = !on;
  319.         break;
  320.     }
  321.     break;
  322.  
  323.      case V_INTEGER:
  324.  
  325.     switch (var->var_op) {
  326.      case 0:
  327.      case 1:
  328.         INT_VAR = value;        
  329.         break;
  330.  
  331.      case 2:
  332.      case 3:
  333.         if (!on) value = -1;
  334.         INT_VAR = value;        
  335.         break;
  336.     }
  337.     return (var->var_op & 1);
  338.     
  339.      case V_KEY:
  340.     switch (var->var_op) {
  341.      case 0:
  342.         if (val_string) {
  343.         if (*val_string) adjust(val_string + 1); /* #N is valid */
  344.         KEY_VAR = parse_key(val_string);
  345.         }
  346.         break;
  347.     }
  348.     break;
  349.     
  350.      case V_SPECIAL:
  351.     
  352.     switch (var->var_op) {
  353.      case 1:
  354.         if (val_string) {
  355.         adjust(val_string);
  356.         news_record = home_relative(val_string);
  357.         mail_record = news_record;
  358.         }
  359.         break;
  360.         
  361.      case 2:
  362.         also_read_articles = on;
  363.         article_limit = (on && value > 0) ? value : -1;
  364.         break;
  365.     }        
  366.     break;
  367.     }
  368.     return 0;
  369. }
  370.     
  371. static adjust(str)
  372. register char *str;
  373. {
  374.     if (str == NULL) return;
  375.     while (*str && !isspace(*str) && *str != '#') str++;
  376.     *str = NUL;
  377. }
  378.  
  379.  
  380. disp_variables()
  381. {
  382.     char *str, *key_name(), *pushed;
  383.     int i, b;
  384.     register struct variable_defs *var;
  385.     
  386.     if (in_init) return;
  387.  
  388.     pg_init(0, 1);
  389.     
  390.     clrdisp();
  391.     pg_next();
  392.     so_printf("\1Variable settings:\1");
  393.  
  394.     for (var = variables; var < &variables[TABLE_SIZE]; var++) {
  395.     pushed = var_on_stack(var) ? ">" : " ";
  396.     switch (VAR_TYPE) {
  397.      case V_STRING:
  398.         str = (var->var_op == 1) ? CBUF_VAR : STR_VAR;
  399.         if (str == NULL) str = "";
  400.         
  401.         if (pg_next() < 0) goto out;
  402.         printf("%s %-20.20s = \"%s\"\n", pushed, var->var_name, str);
  403.         break;
  404.  
  405.      case V_BOOLEAN:
  406.         if (pg_next() < 0) goto out;
  407.         b = BOOL_VAR;
  408.         if (var->var_op == 2 || var->var_op == 4) b = !b;
  409.         printf("%s %-20.20s %s\n", pushed, var->var_name, b ? "" : "= off");
  410.         break;
  411.         
  412.      case V_INTEGER:
  413.         i = INT_VAR;
  414.         if (pg_next() < 0) goto out;
  415.         printf("%s %-20.20s = %d\n", pushed, var->var_name, i);
  416.         break;
  417.         
  418.      case V_KEY:
  419.         if (pg_next() < 0) goto out;
  420.         printf("%s %-20.20s = %s\n", pushed, var->var_name, key_name(KEY_VAR));
  421.         break;
  422.         
  423.      case V_SPECIAL:
  424.         switch (var->var_op) {
  425.          case 1:
  426.         break;
  427.          case 2:
  428.         if (also_read_articles) {
  429.             if (pg_next() < 0) goto out;
  430.             printf("%s %-20.20s = %d\n", pushed, var->var_name, article_limit);
  431.         }
  432.         break;
  433.         }
  434.         break;
  435.     }
  436.     }
  437.     
  438. out:
  439.     pg_end();
  440. }
  441.  
  442. toggle_variable(variable)
  443. char *variable;
  444. {
  445.     register struct variable_defs *var;
  446.     
  447.     if ((var = lookup_variable(variable)) == NULL) return;
  448.     if (VAR_TYPE != V_BOOLEAN) {
  449.     init_message("variable %s is not boolean", variable);
  450.     return;
  451.     }
  452.     
  453.     BOOL_VAR = !BOOL_VAR;
  454. }
  455.  
  456.  
  457. test_variable(expr)
  458. char *expr;
  459. {
  460.     char *variable;
  461.     register struct variable_defs *var;
  462.     int res = -1;
  463.     
  464.     variable = expr;
  465.     if ((expr = strchr(variable, '=')) == NULL) 
  466.     goto err;
  467.     
  468.     *expr++ = NUL;
  469.     
  470.     if ((var = lookup_variable(variable)) == NULL) {
  471.     msg("testing unknown variable %s=%s", variable, expr);
  472.     goto out;
  473.     }    
  474.  
  475.     switch (VAR_TYPE) {
  476.     
  477.      case V_BOOLEAN:
  478.     res = BOOL_VAR;
  479.     
  480.     if (strcmp(expr, "on") == 0) break;
  481.     if (strcmp(expr, "off") == 0) {
  482.         res = !res;
  483.         break;
  484.     }
  485.     msg("boolean variables must be tested =on or =off");
  486.     break;
  487.     
  488.      case V_INTEGER:
  489.     res = (INT_VAR == atoi(expr)) ? 1 : 0;
  490.     break;
  491.     
  492.      default:
  493.     msg("%s: cannot only test boolean and integer variables", variable);
  494.     break;
  495.     }
  496.  out:
  497.     *--expr = '=';
  498.  err:
  499.     return res;
  500. }
  501.  
  502.  
  503. var_completion(path, index)
  504. char *path;
  505. int index;
  506. {
  507.     static char *head, *tail = NULL;
  508.     static int len;
  509.     static struct variable_defs *var, *help_var;
  510.  
  511.     if (index < 0) return 0;
  512.  
  513.     if (path) {
  514.     head = path;
  515.     tail = path + index;
  516.     while (*head && isspace(*head)) head++;
  517.     if (strncmp(head, "no", 2) == 0) {
  518.         head += 2;
  519.         if (*head == '-') head++;
  520.     }
  521.     
  522.     help_var = var = variables;
  523.     len = tail - head;
  524.     
  525.     return 1;
  526.     }
  527.     
  528.     if (index) {
  529.     list_completion((char *)NULL);
  530.     
  531.     for (;; help_var++) {
  532.         if (help_var >= &variables[TABLE_SIZE]) {
  533.         help_var = variables;
  534.         break;
  535.         }
  536.         
  537.         index = strncmp(help_var->var_name, head, len);
  538.         if (index < 0) continue;
  539.         if (index > 0) {
  540.         help_var = variables;
  541.         break;
  542.         }
  543.         if (list_completion(help_var->var_name) == 0) break;
  544.     }
  545.     fl;
  546.     return 1;
  547.     }
  548.  
  549.     for (; var < &variables[TABLE_SIZE]; var++) {
  550.     if (len == 0) 
  551.         index = 0;
  552.     else
  553.         index = strncmp(var->var_name, head, len);
  554.     if (index < 0) continue;
  555.     if (index > 0) break;
  556.     sprintf(tail, "%s ", var->var_name + len);
  557.     var++;
  558.     return 1;
  559.     }
  560.     return 0;
  561. }
  562.  
  563. static struct var_stack {
  564.     struct var_stack *next;
  565.     struct variable_defs *v;
  566.     union {
  567.     int ivar;
  568.     int bool;
  569.     char key;
  570.     char *str;
  571.     } value;
  572. } *var_stack = NULL, *vs_pool = NULL;
  573.  
  574. mark_var_stack()
  575. {
  576.     register struct var_stack *vs;
  577.     
  578.     if (vs_pool) {
  579.     vs = vs_pool;
  580.     vs_pool = vs->next;
  581.     } else {
  582.     vs = (struct var_stack *)calloc(1, sizeof(struct var_stack));
  583.     mem_check((char *)vs, 1, "var structure");
  584.     }
  585.     vs->next = var_stack;
  586.     var_stack = vs;
  587.     vs->v = NULL;
  588. }
  589.  
  590. push_variable(variable)
  591. char *variable;
  592. {
  593.     register struct variable_defs *var;
  594.     register struct var_stack *vs;
  595.     
  596.     if (strncmp(variable, "no", 2) == 0) {
  597.     variable += 2;
  598.     if (variable[0] == '-') variable++;
  599.     }
  600.     
  601.     if ((var = lookup_variable(variable)) == NULL) {
  602.     msg("pushing unknown variable %s", variable);
  603.     return 0;
  604.     }    
  605.  
  606.     mark_var_stack();
  607.     vs = var_stack;
  608.     vs->v = var;
  609.     
  610.     switch (VAR_TYPE) {
  611.     
  612.      case V_STRING:
  613.  
  614.     switch (var->var_op) {
  615.      case 0:    /* if we update one of these variables,    */
  616.      case 2:    /* new storage will be allocated for it */
  617.      case 3:    /* so it is ok just to save the pointer */
  618.         vs->value.str = STR_VAR;
  619.         break;
  620.  
  621.      case 1:    /* we free this memory when restored    */
  622.         vs->value.str = copy_str(CBUF_VAR);
  623.         break;
  624.     }
  625.     break;
  626.     
  627.      case V_BOOLEAN:
  628.     vs->value.bool = BOOL_VAR;
  629.     break;
  630.     
  631.      case V_INTEGER:
  632.     vs->value.ivar = INT_VAR;
  633.     break;
  634.     
  635.      case V_KEY:
  636.     vs->value.key = KEY_VAR;
  637.     break;
  638.     
  639.      case V_SPECIAL:
  640.     msg("Cannot push pseudo variable %s", var->var_name);
  641.     break;
  642.     }
  643.     
  644.     return 1;
  645. }
  646.     
  647. restore_variables()
  648. {
  649.     register struct variable_defs *var;
  650.     register struct var_stack *vs, *vs1;
  651.     
  652.     vs = var_stack; 
  653.  
  654.     while (vs != NULL) {
  655.     if ((var = vs->v) == NULL) {
  656.         var_stack = vs->next;
  657.         vs->next = vs_pool;
  658.         vs_pool = vs;
  659.         return;
  660.     }
  661.     
  662.     switch (VAR_TYPE) {
  663.         
  664.      case V_STRING:
  665.         switch (var->var_op) {
  666.          case 0:    /* only restore the string if changed; then we    */
  667.          case 2:    /* can also free the memory occupied by the    */
  668.          case 3:    /* 'new' value (if not NULL)            */
  669.         if (STR_VAR != vs->value.str) {
  670.             if (STR_VAR != NULL) free(STR_VAR);
  671.             STR_VAR = vs->value.str;
  672.         }
  673.         break;
  674.         
  675.          case 1:    /* it fitted before, so it will fit againg */
  676.         strcpy(CBUF_VAR, vs->value.str);
  677.         free(vs->value.str);
  678.         break;
  679.         }
  680.         break;
  681.         
  682.      case V_BOOLEAN:
  683.         BOOL_VAR = vs->value.bool;
  684.         break;
  685.         
  686.      case V_INTEGER:
  687.         INT_VAR = vs->value.ivar;
  688.         break;
  689.         
  690.      case V_KEY:
  691.         KEY_VAR = vs->value.key;
  692.         break;
  693.         
  694.      case V_SPECIAL:    /* these are not saved, so... */
  695.         break;
  696.     }
  697.  
  698.     vs1 = vs->next;
  699.     vs->next = vs_pool;
  700.     vs_pool = vs;
  701.     vs = vs1;
  702.     }
  703.     var_stack = NULL;
  704. }
  705.  
  706. static var_on_stack(var)
  707. register struct variable_defs *var;
  708. {
  709.     register struct var_stack *vs;
  710.  
  711.     for (vs = var_stack; vs; vs = vs->next)
  712.     if (vs->v == var) return 1;
  713.     return 0;
  714. }
  715.